package org.lab.mtga.core.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

@Entity
@Table(name = "CARD")
public class Card {

	@Id
	@GeneratedValue
	@Column(name = "ID")
	private Long id;

	@Column(name = "CARD_NAME", length = 64, nullable = false)
	private String name;

	@ElementCollection(fetch = FetchType.EAGER)
	@Enumerated(EnumType.STRING)
	private List<CardType> types;

	@ElementCollection
	private List<String> subtypes;

	@Lob
	@Basic(fetch = FetchType.LAZY)
	@Column(name = "CARD_TEXT", columnDefinition = "BLOB")
	private String text;

	@Column(name = "CMC_STRING", length = 16)
	private String cmcString;

	@Column(name = "CMC_COUNT")
	private Integer cmcCount;

	@Column(name = "POWER")
	private String power;

	@Column(name = "TOUGHNESS")
	private String toughness;

	@Column(name = "LOYALTY")
	private Integer loyalty;

	@Column(name = "LEGENDARY")
	private Boolean legendary;

	@Column(name = "EXTERNAL_IMAGE_URL")
	private String externalImageUrl;

	@Column(name = "SCANNED")
	@Temporal(TemporalType.TIMESTAMP)
	private Date scanned;

	@Column(name = "PARSE_RESULT", length = 16)
	@Enumerated(EnumType.STRING)
	private ParseResult parseResult;

	@Transient
	private Map<ManaSource, Integer> cmc;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return name;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public String getCmcString() {
		return cmcString;
	}

	public void setCmcString(String cmc) {
		this.cmcString = cmc;
	}

	public String getExternalImageUrl() {
		return externalImageUrl;
	}

	public void setExternalImageUrl(String externalUrl) {
		this.externalImageUrl = externalUrl;
	}

	public Map<ManaSource, Integer> getCmc() {
		return cmc;
	}

	public void setCmc(Map<ManaSource, Integer> cmc) {
		this.cmc = cmc;
	}

	public Integer getCmcCount() {
		return cmcCount;
	}

	public void setCmcCount(Integer cmcCount) {
		this.cmcCount = cmcCount;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Date getScanned() {
		return scanned;
	}

	public void setScanned(Date scanned) {
		this.scanned = scanned;
	}

	public ParseResult getParseResult() {
		return parseResult;
	}

	public void setParseResult(ParseResult parseResult) {
		this.parseResult = parseResult;
	}

	public List<String> getSubtypes() {
		return subtypes;
	}

	public void setSubtypes(List<String> subtypes) {
		this.subtypes = subtypes;
	}

	public String getPower() {
		return power;
	}

	public void setPower(String power) {
		this.power = power;
	}

	public String getToughness() {
		return toughness;
	}

	public void setToughness(String toughness) {
		this.toughness = toughness;
	}

	public Integer getLoyalty() {
		return loyalty;
	}

	public void setLoyalty(Integer loyalty) {
		this.loyalty = loyalty;
	}

	public Boolean getLegendary() {
		return legendary;
	}

	public void setLegendary(Boolean legendary) {
		this.legendary = legendary;
	}

	public List<CardType> getTypes() {
		return types;
	}

	public void setTypes(List<CardType> types) {
		this.types = types;
	}

	public void addCardType(CardType type) {
		if (types == null) {
			types = new ArrayList<CardType>();
		}
		if (!types.contains(type)) {
			types.add(type);
		}
	}

	public void addCardSubtype(String subtype) {
		if (subtypes == null) {
			subtypes = new ArrayList<String>();
		}
		if (!subtypes.contains(subtype)) {
			subtypes.add(subtype);
		}
	}

	public boolean matchesType(CardType type) {
		if (types != null) {
			for (CardType i : types) {
				if (i == type) {
					return true;
				}
			}
		}
		return false;
	}
}
